package com.itheima.service.impl;


import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.itheima.Enum.ProjectStatusEnum;
import com.itheima.entity.Preject;
import com.itheima.mapper.PrejectMapper;
import com.itheima.pojo.jo.ExcelStatisticsJo;
import com.itheima.pojo.jo.ProjectStatisticsJo;
import com.itheima.pojo.po.ProjectExportPo;
import com.itheima.pojo.po.ProjectStatisticsPo;
import com.itheima.query.ProjectPageQuery;
import com.itheima.result.PageResult;
import com.itheima.service.PrejectService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;

import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.*;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;


/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author guanhuaer
 * @since 2024-09-05
 */
@Service
public class PrejectServiceImpl extends ServiceImpl<PrejectMapper, Preject> implements PrejectService {

    @Autowired
    private PrejectMapper prejectMapper;

    /**
     * 新增项目
     *
     * @param preject
     */
    @Override
    public void projectAdd(Preject preject) {
        preject.setIsSubmit(0);
        preject.setStatus(ProjectStatusEnum.TOREVIEW.getStatus());
        preject.setCreateTime(LocalDateTime.now());
        prejectMapper.insertProjectAdd(preject);
    }
    /**
     * 分页查询
     *
     * @return
     */
    @Override
    public List<Preject> projectPage(ProjectPageQuery projectPageQuery) {
        System.out.println(projectPageQuery.getUsername());
        PageHelper.startPage(projectPageQuery.getPageNum(), projectPageQuery.getPageSize());
        List<Preject> prejects = prejectMapper.selectPages(projectPageQuery);
        return prejects;
    }
    /**
     * 根据id就行删除
     *
     * @param string
     */
    @Override
    public void Delects(String string) {
        String[] strings = string.split(",");
        ArrayList<Integer> list = new ArrayList<>();
        for (String item : strings) {
            prejectMapper.Deldect(Integer.valueOf(item));
        }
    }
    @Override
    public PageResult pageQuery(ProjectPageQuery query) {
        PageHelper.startPage(query.getPageNum(), query.getPageSize());
        Page<Preject> page = prejectMapper.page(query);
        return new PageResult(page.getTotal(), page.getResult());
    }
    @Override
    public void projectEdit(Preject preject) {
        preject.setMenber(preject.getMenber().toString());
        prejectMapper.projectEdit(preject);
    }
    @Override
    public ProjectStatisticsPo getProjectStatistics(ProjectStatisticsJo projectJo) {
        //当前集合存放从begin到end内的时间段数据
        LocalDate end = projectJo.getEnd();
        LocalDate begin = projectJo.getBegin();
        List<LocalDate> localDates = new ArrayList<>();
        localDates.add(begin);
        while (!begin.equals(end)) {
            //获取begin后一天的数据
            begin = begin.plusDays(1);
            localDates.add(begin);
        }
        //将时间列表转为字符串
        String join = StringUtils.join(localDates, ",");
        //每一天项目总量
        List<Integer> cumulativeUsersList = new ArrayList<>();
        //每一天项目新增的量
        List<Integer> newUsersList = new ArrayList<>();
        //每一天项目访问量
        List<Integer> visitorsList = new ArrayList<>();
        //每一天项目浏览量
        List<Integer> pageViewsList = new ArrayList<>();
        for (LocalDate localDate : localDates) {
            LocalDateTime beginTime = LocalDateTime.of(localDate, LocalTime.MIN);
            LocalDateTime endTime = LocalDateTime.of(localDate, LocalTime.MAX);
            Map map = new HashMap<>();
            map.put("end", endTime);
            map.put("type", projectJo.getType());
            //总的项目量
            cumulativeUsersList.add(prejectMapper.countByMap(map));
            visitorsList.add(prejectMapper.countViewMap(map));
            pageViewsList.add(prejectMapper.countViewMap(map));
            //新增项目量
            map.put("begin", beginTime);
            newUsersList.add(prejectMapper.countByMap(map));
        }
        String cumulativeUsers = StringUtils.join(cumulativeUsersList, ",");
        String newUsers = StringUtils.join(newUsersList, ",");
        String visitors = StringUtils.join(visitorsList, ",");
        String pageViews = StringUtils.join(pageViewsList, ",");
        double cumulativeUser = 0.00;
        double newUser = 0.00;
        double visitor = 0.00;
        double pageView = 0.00;
        LocalDateTime beginTime = LocalDateTime.of(projectJo.getBegin(), LocalTime.MIN);
        LocalDateTime endTime = LocalDateTime.of(projectJo.getEnd(), LocalTime.MAX);
        Map map = new HashMap<>();
        map.put("end", endTime);
        map.put("type", projectJo.getType());
        cumulativeUser = prejectMapper.countByMap(map);
        visitor = prejectMapper.countByMap(map);
        pageView= prejectMapper.countByMap(map);
        for (int i = 0; i < newUsersList.size()-1; i++) {
            newUser+=newUsersList.get(i);
        }
        Integer newUserNuber = (int) newUser;
        Map map1 = new HashMap<>();
        beginTime = LocalDateTime.of(projectJo.getBegin().plusDays(-1*localDates.size()), LocalTime.MIN);
        endTime = LocalDateTime.of(projectJo.getBegin().plusDays(-1), LocalTime.MAX);
        map1.put("end", endTime);
        map1.put("type", projectJo.getType());
        double cumulativeUse = prejectMapper.countByMap(map1);
        double visito = prejectMapper.countByMap(map1);
        double pageVie = prejectMapper.countByMap(map1);
        map1.put("begin", beginTime);
        double newUse = prejectMapper.countByMap(map1);
        cumulativeUser = Double.parseDouble(String.format("%.3f",(cumulativeUser-cumulativeUse)/(cumulativeUse>0?cumulativeUse:1)*100));
        newUser = Double.parseDouble(String.format("%.3f",(newUser-newUse)/(newUse>0?newUse:1)*100));
        visitor = Double.parseDouble(String.format("%.3f",(visitor-visito)/(visito>0?visito:1)*100));
        pageView = Double.parseDouble(String.format("%.3f",(pageView-pageVie)/(pageVie>0?pageVie:1)*100));
        return ProjectStatisticsPo.builder()
                .cumulativeUsers(cumulativeUsers)
                .newUsers(newUsers)
                .pageViews(pageViews)
                .visitors(visitors)
                .dateList(join)
                .cumulativeUser(cumulativeUser)
                .newUser(newUser)
                .visitor(visitor)
                .pageView(pageView)
                .build();
    }
    public ProjectExportPo getProjectExport(ExcelStatisticsJo projectJo) {
        //当前集合存放从begin到end内的时间段数据
        LocalDate end = projectJo.getEnd();
        LocalDate begin = projectJo.getBegin();
        List<LocalDate> localDates = new ArrayList<>();
        localDates.add(begin);
        while (!begin.equals(end)) {
            //获取begin后一天的数据
            begin = begin.plusDays(1);
            localDates.add(begin);
        }
        //将时间列表转为字符串
        String join = StringUtils.join(localDates, ",");
        //每一天项目总量
        List<Integer> cumulativeUsersList = new ArrayList<>();
        //每一天项目新增的量
        List<Integer> newUsersList = new ArrayList<>();
        //每一天项目访问量
        List<Integer> visitorsList = new ArrayList<>();
        //每一天项目浏览量
        List<Integer> pageViewsList = new ArrayList<>();
        for (LocalDate localDate : localDates) {
            LocalDateTime beginTime = LocalDateTime.of(localDate, LocalTime.MIN);
            LocalDateTime endTime = LocalDateTime.of(localDate, LocalTime.MAX);
            Map map = new HashMap<>();
            map.put("end", endTime);
            map.put("type", projectJo.getType());
            //总的项目量
            cumulativeUsersList.add(prejectMapper.countByMap(map));
            visitorsList.add(prejectMapper.countViewMap(map));
            pageViewsList.add(prejectMapper.countViewMap(map));
            //新增项目量
            map.put("begin", beginTime);
            newUsersList.add(prejectMapper.countByMap(map));
        }
        double cumulativeUser = 0.00;
        double newUser = 0.00;
        double visitor = 0.00;
        double pageView = 0.00;

        LocalDateTime beginTime = LocalDateTime.of(projectJo.getBegin(), LocalTime.MIN);
        LocalDateTime endTime = LocalDateTime.of(projectJo.getEnd(), LocalTime.MAX);
        Map map = new HashMap<>();
        map.put("end", endTime);
        map.put("type", projectJo.getType());
        cumulativeUser = prejectMapper.countByMap(map);
        visitor = prejectMapper.countByMap(map);
        pageView= prejectMapper.countByMap(map);
        for (int i = 0; i < newUsersList.size()-1; i++) {
            newUser+=newUsersList.get(i);
        }
        Integer newUserNuber = (int) newUser;
        Map map1 = new HashMap<>();
        beginTime = LocalDateTime.of(projectJo.getBegin().plusDays(-1*localDates.size()), LocalTime.MIN);
        endTime = LocalDateTime.of(projectJo.getBegin().plusDays(-1), LocalTime.MAX);
        map1.put("end", endTime);
        map1.put("type", projectJo.getType());
        double cumulativeUse = prejectMapper.countByMap(map1);
        double visito = prejectMapper.countByMap(map1);
        double pageVie = prejectMapper.countByMap(map1);
        map1.put("begin", beginTime);
        double newUse = prejectMapper.countByMap(map1);
        cumulativeUser = Double.parseDouble(String.format("%.3f",(cumulativeUser-cumulativeUse)/(cumulativeUse>0?cumulativeUse:1)*100));
        newUser = Double.parseDouble(String.format("%.3f",(newUser-newUse)/(newUse>0?newUse:1)*100));
        visitor = Double.parseDouble(String.format("%.3f",(visitor-visito)/(visito>0?visito:1)*100));
        pageView = Double.parseDouble(String.format("%.3f",(pageView-pageVie)/(pageVie>0?pageVie:1)*100));
        return ProjectExportPo.builder()
                .cumulativeUsers(cumulativeUsersList.get(cumulativeUsersList.size()-1))
                .newUsers(newUserNuber)
                .pageViews(pageViewsList.get(pageViewsList.size()-1))
                .visitors(visitorsList.get(visitorsList.size()-1))
                .dateList(localDates)
                .cumulativeUser(cumulativeUser)
                .newUser(newUser)
                .visitor(visitor)
                .pageView(pageView)
                .build();
    }
    @Override
    public void exprotBusinsData(ExcelStatisticsJo projectJo, HttpServletResponse response) throws IOException {
        // 查询数据库，获取数据，根据传输的时间段
        LocalDate dataBegin = projectJo.getBegin();
        LocalDate dataEnd = projectJo.getEnd();
        LocalDateTime begin = LocalDateTime.of(dataBegin, LocalTime.MIN);
        LocalDateTime end = LocalDateTime.of(dataEnd, LocalTime.MAX);
        //获取数据
        ProjectExportPo exportPo = getProjectExport(projectJo);
        //通过POI将数据写入到excel文件中
        //通过类加载器加载文件获得一个对象
        InputStream in = this.getClass().getClassLoader().getResourceAsStream("template/项目统计报表模板.xlsx");

        //基于模板文件创建一个新的Excel文件
        XSSFWorkbook excel = new XSSFWorkbook(in);
        //获取表格Sheet1页
        XSSFSheet sheet = excel.getSheet("Sheet1");
        //填充数据-时间，运营数据报表
        sheet.getRow(2).getCell(0).setCellValue("时间：  " + dataBegin + "   至    " + dataEnd);
        //填充 概览数据  累计项目 新增项目 访问数 浏览量 和各个环比增长
        //获得第五行 填充数据
        XSSFRow row = sheet.getRow(4);
        row.createCell(1).setCellValue(exportPo.getCumulativeUsers());
        row.createCell(3).setCellValue(exportPo.getCumulativeUser());
        row.createCell(5).setCellValue(exportPo.getVisitors());
        row.createCell(7).setCellValue(exportPo.getVisitor());
        XSSFRow row1 = sheet.getRow(5);
        row1.createCell(1).setCellValue(exportPo.getNewUsers());
        row1.createCell(3).setCellValue(exportPo.getNewUser());
        row1.createCell(5).setCellValue(exportPo.getPageViews());
        row1.createCell(7).setCellValue(exportPo.getPageView());
        Integer yeshu = 0;
        for (int i = 0; i < exportPo.getDateList().size(); i++) {
            //查询exportPo.getDateList()中每一天的项目数据
            LocalDateTime begins = LocalDateTime.of(exportPo.getDateList().get(i), LocalTime.MIN);
            LocalDateTime ends = LocalDateTime.of(exportPo.getDateList().get(i), LocalTime.MAX);
            List<Preject> prejects = prejectMapper.selectExport(begins, ends, projectJo.getType());
            System.out.println(prejects);
            if (prejects.size() > 0) {
                for (int j = 0; j < prejects.size(); j++) {
                    XSSFRow row2 = sheet.createRow(8 + yeshu);
                    row2.createCell(0).setCellValue((exportPo.getDateList().get(i)).toString());
                    System.out.println();
                    System.out.println(exportPo.getDateList().get(i));
                    System.out.println();
                    System.out.println();
                     row2.createCell(1).setCellValue(prejects.get(j).getTitle());
                     row2.createCell(2).setCellValue(prejects.get(j).getProtype());
                     row2.createCell(3).setCellValue(prejects.get(j).getUsername());
                     row2.createCell(4).setCellValue(prejects.get(j).getMenber());
                     row2.createCell(5).setCellValue(prejects.get(j).getContent());
                     yeshu+=1;
                }
            }
        }
        String fileName = projectJo.getExcelType();
        if (fileName.equals("")){
            fileName = "项目统计报告模板";
        }
        FileOutputStream out = new FileOutputStream(new File("D:\\cad\\vue\\毕业论文\\guanhuaer\\roomhotel\\src\\main\\resources\\static\\img\\real\\"+fileName+".xlsx"));
        //通过输出流将内存中的Excel文件写入到磁盘上
        excel.write(out);
        //关闭资源
        out.flush();
        out.close();
        excel.close();
    }

    /**
     * 批量新增项目
     * @param prejects
     */
    @Override
    public void projectBatchAdd(List<Preject> prejects) {
        for (Preject preject : prejects) {
            preject.setCreateTime(LocalDateTime.now());
        }
        prejectMapper.projectBatchAdd(prejects);
    }
}
